package nl.rug.ml.dobbelen.game;

import java.util.List;
import java.util.Random;

/**
 * An abstract class representing a dice, since we still don't know how it will
 * generate output.
 * 
 * @author Do Bich Ngoc (bichngocdo89@gmail.com)
 * 
 */
public abstract class Dice implements Comparable<Dice> {

	private static Random random = new Random();

	/**
	 * Indicate that every dice is unique.
	 */
	private int id;

	/**
	 * The value of the last throw will be kept here.
	 */
	protected int value;

	/**
	 * The number of turn.
	 */
	protected int turn;

	public Dice() {
		id = random.nextInt();
		value = 0;
		turn = 0;
	}

	public int getValue() {
		return value;
	}

	public int getTurn() {
		return turn;
	}

	public void reset() {
		value = 0;
		turn = 0;
	}

	/**
	 * Use for testing purpose only.
	 * 
	 * @param value
	 * @param turn
	 */
	public void setParameters(int value, int turn) {
		this.value = value;
		this.turn = turn;
	}

	/**
	 * Use for testing purpose only.
	 * 
	 * @param dices
	 * @param parameters
	 */
	public static void setDiceParameters(List<Dice> dices, int... parameters) {
		if (dices.size() * 2 != parameters.length) {
			System.err.println("The number of dices and the number of parameters are incompatible");
			return;
		}
		int k = 0;
		for (Dice dice : dices) {
			dice.setParameters(parameters[k++], parameters[k++]);
		}
	}

	public abstract int throwIt(int turn);

	@Override
	public String toString() {
		return "Dice [" + value + "(" + turn + ")]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		result = prime * result + turn;
		result = prime * result + value;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof Dice)) {
			return false;
		}
		Dice other = (Dice) obj;
		if (id != other.id) {
			return false;
		}
		if (turn != other.turn) {
			return false;
		}
		if (value != other.value) {
			return false;
		}
		return true;
	}

	@Override
	public int compareTo(Dice o) {
		if (value != o.value) {
			return value - o.getValue();
		}
		else {
			return turn - o.getTurn();
		}
	}

}
